#!/usr/local/bin/perl -w

use Test::More qw(no_plan);
use lib "../App-Context/lib";
use lib "../../App-Context/lib";
use lib "lib";
use lib "../lib";

use_ok("App");
use_ok("App::Repository");
use strict;

{
    #$App::trace = 1;
    #$App::trace = 1;
    is(App::Repository->evaluate_constant_expression("1"), 1, "eval: 1");
    is(App::Repository->evaluate_constant_expression("-1.5"), -1.5, "eval: -1.5");
    is(App::Repository->evaluate_constant_expression(" 2   "), 2, "eval: 2");
    is(App::Repository->evaluate_constant_expression("  -1.5"), -1.5, "eval: [sp]-1.5");
    is(App::Repository->evaluate_constant_expression("-1.5   "), -1.5, "eval: -1.5[sp]");
    is(App::Repository->evaluate_constant_expression("  -1.5   "), -1.5, "eval: [sp]-1.5[sp]");
    is(App::Repository->evaluate_constant_expression("2+4"), 6, "eval: 2+4");
    is(App::Repository->evaluate_constant_expression("2-4"), -2, "eval: 2-4");
    is(App::Repository->evaluate_constant_expression("2*4"), 8, "eval: 2*4");
    is(App::Repository->evaluate_constant_expression("2/4"), .5, "eval: 2/4");
    is(App::Repository->evaluate_constant_expression("2+-4"), -2, "eval: 2+-4");
    is(App::Repository->evaluate_constant_expression("2--4"), 6, "eval: 2--4");
    is(App::Repository->evaluate_constant_expression("2*-4"), -8, "eval: 2*-4");
    is(App::Repository->evaluate_constant_expression("2/-4"), -.5, "eval: 2/-4");
    is(App::Repository->evaluate_constant_expression("-2+-4"), -6, "eval: -2+-4");
    is(App::Repository->evaluate_constant_expression("-2--4"), 2, "eval: -2--4");
    is(App::Repository->evaluate_constant_expression("-2*-4"), 8, "eval: -2*-4");
    is(App::Repository->evaluate_constant_expression("-2/-4"), .5, "eval: -2/-4");
    is(App::Repository->evaluate_constant_expression("1+2*3"), 7, "eval: 1+2*3");
    is(App::Repository->evaluate_constant_expression("1*2+3"), 5, "eval: 1*2+3");
    is(App::Repository->evaluate_constant_expression("1*(2+3)"), 5, "eval: 1*(2+3)");
    is(App::Repository->evaluate_constant_expression("((1-(2*3))+(12-5))*3"), 6, "eval: ((1-(2*3))+(12-5))*3");
    is(App::Repository->evaluate_constant_expression("((1-(abs(-2*3)))+(max(12,2,3)-abs(5)))*3"), 6, "eval: ((1-(abs(-2*3)))+(max(12,2,3)-abs(5)))*3");
    is(App::Repository->evaluate_constant_expression("(2/abs(-1))"), 2, "(2/abs(-1))");
    is(App::Repository->evaluate_constant_expression("abs(2/-1)"), 2, "abs(2/-1)");
    is(App::Repository->evaluate_constant_expression("max(-1,0,6,3)"), 6, "eval: max(-1,0,6,3)");
    is(App::Repository->evaluate_constant_expression("min(-1,0,6,3)"), -1, "eval: min(-1,0,6,3)");
    ok(App::Repository->evaluate_constant_expression("max(-1.3,-3e-1)") == -.3, "eval: max(-1.3,-3e-1)");
    ok(App::Repository->evaluate_constant_expression("min(-1.3,-3e-1)") == -1.3, "eval: min(-1.3,-3e-1)");
    is(App::Repository->evaluate_constant_expression("1 > 2"), 0, "eval: 1 > 2");
    is(App::Repository->evaluate_constant_expression("(1.5*3)>2"), 1, "eval: (1.5*3)>2");
    is(App::Repository->evaluate_constant_expression("(1.5*3)=4.5"), 1, "eval: (1.5*3)=4.5");
    is(App::Repository->evaluate_constant_expression("(1.5*3)=4"), 0, "eval: (1.5*3)=4");
    is(App::Repository->evaluate_constant_expression("2<-1"),  0, "eval: 2<-1");
    is(App::Repository->evaluate_constant_expression("2<2"),   0, "eval: 2<2");
    is(App::Repository->evaluate_constant_expression("0<2"),   1, "eval: 0<2");
    is(App::Repository->evaluate_constant_expression("2<=-1"), 0, "eval: 2<=-1");
    is(App::Repository->evaluate_constant_expression("2<=2"),  1, "eval: 2<=2");
    is(App::Repository->evaluate_constant_expression("0<=2"),  1, "eval: 0<=2");
    is(App::Repository->evaluate_constant_expression("2>-1"),  1, "eval: 2>-1");
    is(App::Repository->evaluate_constant_expression("2>2"),   0, "eval: 2>2");
    is(App::Repository->evaluate_constant_expression("0>2"),   0, "eval: 0>2");
    is(App::Repository->evaluate_constant_expression("2>=-1"), 1, "eval: 2>=-1");
    is(App::Repository->evaluate_constant_expression("2>=2"),  1, "eval: 2>=2");
    is(App::Repository->evaluate_constant_expression("0>=2"),  0, "eval: 0>=2");
    is(App::Repository->evaluate_constant_expression("2=-1"),  0, "eval: 2=-1");
    is(App::Repository->evaluate_constant_expression("2=2"),   1, "eval: 2=2");
    is(App::Repository->evaluate_constant_expression("0=2"),   0, "eval: 0=2");
    is(App::Repository->evaluate_constant_expression("2!=-1"), 1, "eval: 2!=-1");
    is(App::Repository->evaluate_constant_expression("2!=2"),  0, "eval: 2!=2");
    is(App::Repository->evaluate_constant_expression("0!=2"),  1, "eval: 0!=2");
    is(App::Repository->evaluate_constant_expression("ifnull(undef,2)"), 2, "eval: ifnull(undef,2)");
    is(App::Repository->evaluate_constant_expression("ifnull(3,2)"),     3, "eval: ifnull(3,2)");
    is(App::Repository->evaluate_constant_expression("if(3>4,5,6)"),     6, "eval: if(3>4,5,6)");
    is(App::Repository->evaluate_constant_expression("if(3<4,5,6)"),     5, "eval: if(3<4,5,6)");
    is(App::Repository->evaluate_constant_expression("case(7)"),         undef, "eval: case(7)");
    is(App::Repository->evaluate_constant_expression("case(7,17)"),      17, "eval: case(7,17)");
    is(App::Repository->evaluate_constant_expression("case(7+2,8,18,9,19)"), 19, "eval: case(7+2,8,18,9,19)");
    is(App::Repository->evaluate_constant_expression("case(7+2,8,18)"), undef, "eval: case(7+2,8,18)");
    is(App::Repository->evaluate_constant_expression("case(7+2,8,18,20)"), 20, "eval: case(7+2,8,18,20)");

    my %values = (
        x  => 3,
        y  => 4,
        r2 => "{x}*{x}+{y}*{y}",
        z  => 0,
        r  => 5,
        pi => 3.1415926535259,
    );
    my @cols = qw(x y r2 z r pi);
    my @values = @values{@cols};
    my (%validx);
    for (my $i = 0; $i <= $#cols; $i++) {
        $validx{$cols[$i]} = $i;
    }

    # tests on rows (hashrefs) of data
    is(App::Repository->evaluate_expression("{x}*{x}+{y}*{y}",\%values), 25, "eval: {x}*{x}+{y}*{y}");
    is(App::Repository->evaluate_expression("{x}/{z}",\%values), undef, "eval: {x}/{z}");
    is(App::Repository->evaluate_expression("{x}/{z}+{y}*{y}",\%values), undef, "eval: {x}/{z}+{y}*{y}");
    is(App::Repository->evaluate_expression("2*{r2}",\%values), 50, "eval: 2*{r2}");

    # tests on rows (arrayrefs) of data
    is(App::Repository->evaluate_expression("{x}*{x}+{y}*{y}",\@values, \%validx), 25, "eval: {x}*{x}+{y}*{y}");
    is(App::Repository->evaluate_expression("{x}/{z}",\@values, \%validx), undef, "eval: {x}/{z}");
    is(App::Repository->evaluate_expression("{x}/{z}+{y}*{y}",\@values, \%validx), undef, "eval: {x}/{z}+{y}*{y}");
    is(App::Repository->evaluate_expression("2*{r2}",\@values, \%validx), 50, "eval: 2*{r2}");
}

exit 0;

